from ...rp_courier_management.functions.price_adjust_rule_fc import PriceAdjustRuleFC
from odoo.exceptions import UserError


class MarketingAdjustmentFunc(object):
    """
    Model:
        满足所有营销调价涉及的算法逻辑

    Param:
        -env:odoo env
    """

    def __init__(self, env):
        self.env = env

    """
       --------------------------------------------------------------------------
       调价相关方法
       Function:
       -validate_history_record:校验调价模板历史记录信息
       -backdoor_get_selected_mail_route:查询到具体的销售模板邮路
       -backdoor_get_adjustment_price_result:Odoo后台获取调价后价格
       """

    def validate_history_record(self, customer_level_ids, customer_category_ids, special_customer_tag, rp_customer_id, code, adjust_for, rp_shipper_id
                                , rp_shipper_value_added_id, rp_shipper_mail_route_id):
        """
        校验调价模板历史记录
        Params:
        -customer_level_ids:客户等级
        -customer_category_ids:客户分类
        -special_customer_tag:特殊客户标志
        -rp_customer_id:特殊客户
        -code:编码
        -adjust_for:调价对象
        -rp_shipper_id:托运商
        -rp_shipper_value_added_id:增值服务
        -rp_shipper_mail_route_id:邮路
        """
        if any([len(customer_level_ids) == 0, len(customer_category_ids) == 0]) and special_customer_tag is False:
            raise UserError('配置错误')
        if special_customer_tag is True:
            # 特殊客户逻辑
            result = self.env['rp.marketing.adjust.price.template'].search([('code', '!=', code), ('special_customer_tag', '=', special_customer_tag), ('rp_customer_id', '=', rp_customer_id), ('template_state', 'in', ['enable', 'await_enable'])])
            conflict_ids = self.validate_adjustment_info_conflict(result, adjust_for, rp_shipper_id, rp_shipper_value_added_id, rp_shipper_mail_route_id)
            if len(conflict_ids) > 0:
                conflict_codes = ','.join(conflict_ids.mapped(lambda r: r.code))
                raise UserError(f'[{conflict_codes}存在冲突（特殊客户冲突）,请解决冲突后重试！]')
        else:
            base_search = self.env['rp.marketing.adjust.price.template'].search([('code', '!=', code), ('special_customer_tag', '=', special_customer_tag), ('template_state', 'in', ['enable', 'await_enable'])])
            intersection_records = base_search.filtered(lambda r: set(r.customer_category_ids.ids) & set(customer_category_ids) and set(r.customer_level_ids.ids) & set(customer_level_ids))
            conflict_ids = self.validate_adjustment_info_conflict(intersection_records, adjust_for, rp_shipper_id, rp_shipper_value_added_id, rp_shipper_mail_route_id)
            if len(conflict_ids) > 0:
                conflict_codes = ','.join(conflict_ids.mapped(lambda r: r.code))
                raise UserError(f'[{conflict_codes}]存在冲突（等级或分类冲突）,请解决冲突后重试！')

    def validate_adjustment_info_conflict(self, record, adjust_for, rp_shipper_id, rp_shipper_value_added_id, rp_shipper_mail_route_id):
        """
        校验调价信息是否冲突【条件是基本信息未发生冲突的情况】
        Params：
        -record:模板记录
        -adjust_for:调价对象
        -rp_shipper_id:托运商
        -rp_shipper_value_added_id:增值服务
        -rp_shipper_mail_route_id:邮路
        Return:
        -adjust_price_template_ids:调价模板
        """
        if adjust_for == 'all_mail_route':
            # 调价规则为全部邮路
            adjust_price_template_ids = record.filtered(lambda r: r.rp_shipper_id.id == rp_shipper_id and r.adjust_for == 'all_mail_route')
            return adjust_price_template_ids
        if adjust_for == 'single_mail_route':
            # 调价规则为单一邮路
            adjust_price_template_ids = record.filtered(lambda r: r.rp_shipper_id.id == rp_shipper_id and r.rp_shipper_mail_route_id.id == rp_shipper_mail_route_id and r.adjust_for == 'single_mail_route')
            return adjust_price_template_ids
        if adjust_for == 'single_value_add':
            # 调价规则为增值服务
            adjust_price_template_ids = record.filtered(lambda r: r.rp_shipper_id.id == rp_shipper_id and r.rp_shipper_value_added_id.id == rp_shipper_value_added_id and r.adjust_for == 'single_value_add')
            return adjust_price_template_ids

    def backdoor_get_selected_mail_route(self, shipper_mail_route_id, send_city_id, receive_city_id):
        """
        查询到具体的销售模板邮路
        Param:
        -shipper_mail_route_id:邮路ID
        -send_city_id:发送城市
        -receive_city_id:接收城市

        Return:
        -selected_sale_template_mail_route_line:具体的销售模板邮路
        """
        # 查询启用地
        ship_from_group = self.env['res.country.group'].search([('city_ids', 'in', [send_city_id.id])])
        # 查询目的地
        ship_to_group = self.env['res.country.group'].search([('city_ids', 'in', [receive_city_id.id])])
        #  查询到具体的销售模板邮路
        selected_sale_template_mail_route_line = self.env['rp.shipper.sale.template.mail.route.line'].search([('shipper_mail_route_id', '=', shipper_mail_route_id.id), ('active_flag', '=', True),
                                                                                                              ('ship_from_country_group_ids', 'in', ship_from_group.ids), ('ship_to_country_group_ids', 'in', ship_to_group.ids)])
        return selected_sale_template_mail_route_line

    def backdoor_get_adjustment_price_result(self, customer_id, shipper_id, selected_sale_template_mail_route_line, mail_route_adjusted_price,
                                             rp_ship_order_value_added_line_ids):
        """

        获取调价后结果
        Param:
        -customer_id:顾客ID
        -shipper_id:托运商ID
        -selected_sale_template_mail_route_line:所选邮路
        -mail_route_adjusted_price:邮路调后价（营销调价前）
        -rp_ship_order_value_added_line_ids:增值服务明细

        Return:
        -dict:调整后价格
        """
        if customer_id.special_customer_tag:
            related_template_ids = self.env['rp.marketing.adjust.price.template'].search([('rp_customer_id', '=', customer_id.id), ('special_customer_tag', '=', True)])
        else:
            customer_category = customer_id.rp_customer_category.id
            customer_level = customer_id.customer_level.id
            # 查找到符合该用户的调价模板
            related_template_ids = self.env['rp.marketing.adjust.price.template'].search([('template_state', '=', 'enable'), ('customer_category_ids', 'in', [customer_category]), ('customer_level_ids', 'in', [customer_level])])
        # 筛选出是该托运商的所有调价项目
        price_adjustment_ids = related_template_ids.filtered(lambda r: r.rp_shipper_id == shipper_id and r.template_state == 'enable')
        # 所有邮路和单一邮路可以叠加
        related_route_part = price_adjustment_ids.filtered(lambda r: any([r.adjust_for == 'all_mail_route', r.adjust_for == 'single_mail_route' and r.rp_shipper_mail_route_id.id == selected_sale_template_mail_route_line.id]))
        sum_for_route = mail_route_adjusted_price
        for record in related_route_part:
            sum_for_route = PriceAdjustRuleFC(self.env).get_adjusted_price(sum_for_route, record.rp_price_adjust_rule_id)
        # 增值分类
        rp_ship_order_value_added_lines_for_one = rp_ship_order_value_added_line_ids.filtered(lambda r: r.value_added_category == 'one')
        rp_ship_order_value_added_lines_for_two = rp_ship_order_value_added_line_ids.filtered(lambda r: r.value_added_category == 'two')
        # 处理增值服务_单一增值（二类）
        related_added_value_two_part = price_adjustment_ids.filtered(lambda r: r.adjust_for == 'single_value_add' and r.value_added_selection == 'two')
        adjusted_for_added = 0.0
        for record in rp_ship_order_value_added_lines_for_two:
            search_result = related_added_value_two_part.filtered(lambda r: r.rp_shipper_value_added_id.shipper_value_added_id.id == record.value_added_id.id)
            if len(search_result) == 1:
                adjusted_result = PriceAdjustRuleFC(self.env).get_adjusted_price(record.sale_adjusted_price, search_result.rp_price_adjust_rule_id)
                # 更新对应行的数据
                record.write({'adjusted_price_for_marketing': adjusted_result})
                adjusted_for_added += adjusted_result
            else:
                # 如果没有调价规则就加上该项销售调价的结果
                record.write({'adjusted_price_for_marketing': record.sale_adjusted_price})
                adjusted_for_added += record.sale_adjusted_price
        # 处理增值服务_单一增值（只有一类）
        adjusted_for_fulfillment = 0.0  # 对于一类的增值服务统计到头尾程中
        related_added_value_one_part = price_adjustment_ids.filtered(lambda r: r.adjust_for == 'single_value_add' and r.value_added_selection == 'one')
        for record in rp_ship_order_value_added_lines_for_one:
            search_result = related_added_value_one_part.filtered(lambda r: r.rp_shipper_value_added_id.shipper_value_added_id.id == record.value_added_id.id)
            if len(search_result) == 1:
                adjusted_result = PriceAdjustRuleFC(self.env).get_adjusted_price(record.sale_adjusted_price, search_result.rp_price_adjust_rule_id)
                record.write({'adjusted_price_for_marketing': adjusted_result})
                adjusted_for_fulfillment += adjusted_result
            else:
                record.write({'adjusted_price_for_marketing': record.sale_adjusted_price})
                adjusted_for_fulfillment += record.sale_adjusted_price
        # 处理增值服务_所有增值（只有二类）（所有增值和单一增值可以叠加）
        related_added_value_all_part = price_adjustment_ids.filtered(lambda r: r.adjust_for == 'all_value_add')
        for record in rp_ship_order_value_added_lines_for_two:
            # 在以上步骤中进行过单一同类型二类的增值调价
            if record.adjusted_price_for_marketing != 0:
                temp = price = record.adjusted_price_for_marketing
            else:
                temp = price = record.sale_adjusted_price
            for price_adjustment in related_added_value_all_part:
                adjusted_result = PriceAdjustRuleFC(self.env).get_adjusted_price(price, price_adjustment.rp_price_adjust_rule_id)
                price += adjusted_result
            record.write({'adjusted_price_for_marketing': price})
            adjusted_for_added = adjusted_for_added - temp + price
        return {
            'sum_for_route': sum_for_route,
            'sum_for_added': adjusted_for_added,
            'sum_for_fulfillment': adjusted_for_fulfillment,
            'all_price_adjust_price': sum_for_route + adjusted_for_added + adjusted_for_fulfillment,
            'related_template_id': [(6, 0, related_route_part.ids)],
            'adjusted_state': True
        }
